package com.fac.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fac.dto.*;
import com.fac.entity.LeaseOrder;
import com.fac.entity.PaymentRecord;
import com.fac.entity.RepairOrder;
import com.fac.entity.Users;
import com.fac.exception.BusinessException;
import com.fac.mapper.LeaseOrderMapper;
import com.fac.mapper.PaymentRecordMapper;
import com.fac.mapper.RepairOrderMapper;
import com.fac.mapper.UsersMapper;
import com.fac.result.PageResult;
import com.fac.service.PaymentRecordService;
import com.fac.vo.PaymentCreateVO;
import com.fac.vo.PaymentVO;
import com.fac.vo.PaymentAdminVO;
import com.fac.vo.PaymentRefundVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PaymentRecordServiceImpl implements PaymentRecordService {

    @Autowired
    private PaymentRecordMapper paymentRecordMapper;

    @Autowired
    private LeaseOrderMapper leaseOrderMapper;

    @Autowired
    private RepairOrderMapper repairOrderMapper;

    @Autowired
    private UsersMapper usersMapper;

    @Override
    @Transactional
    public PaymentCreateVO create(PaymentCreateDTO createDTO) {
        // 获取订单金额
        BigDecimal amount = getOrderAmount(createDTO);

        // 生成支付编号
        String paymentCode = generatePaymentCode();

        // 创建支付记录
        PaymentRecord record = PaymentRecord.builder()
                .code(paymentCode)
                .orderId(createDTO.getOrderId())
                .orderType(createDTO.getOrderType())
                .amount(amount)
                .paymentType(createDTO.getPaymentType())
                .paymentMethod(createDTO.getPaymentMethod())
                .status(0)
                .build();

        // 保存记录
        paymentRecordMapper.insert(record);

        // 生成支付链接
        String paymentUrl = generatePaymentUrl(record);

        // 返回结果
        return PaymentCreateVO.builder()
                .paymentId(record.getPaymentId())
                .code(record.getCode())
                .amount(record.getAmount())
                .paymentUrl(paymentUrl)
                .build();
    }

    @Override
    public PageResult pageQuery(PaymentPageQueryDTO queryDTO) {
        // 构建查询条件
        LambdaQueryWrapper<PaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(queryDTO.getOrderType() != null, PaymentRecord::getOrderType, queryDTO.getOrderType())
                .orderByDesc(PaymentRecord::getCreatedAt);

        // 分页查询
        Page<PaymentRecord> page = paymentRecordMapper.selectPage(
                new Page<>(queryDTO.getPage(), queryDTO.getSize()),
                wrapper
        );

        // 转换为VO
        List<PaymentVO> voList = page.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult(page.getTotal(), voList);
    }

    @Override
    public PageResult adminPageQuery(PaymentAdminPageQueryDTO queryDTO) {
        // 构建查询条件
        LambdaQueryWrapper<PaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(queryDTO.getStatus() != null, PaymentRecord::getStatus, queryDTO.getStatus())
                .eq(queryDTO.getOrderType() != null, PaymentRecord::getOrderType, queryDTO.getOrderType())
                .orderByDesc(PaymentRecord::getCreatedAt);

        // 如果指定了用户ID，需要先查询用户的订单
        if (queryDTO.getUserId() != null) {
            List<Long> orderIds = getOrderIdsByUserId(queryDTO.getUserId(), queryDTO.getOrderType());
            if (orderIds.isEmpty()) {
                return new PageResult(0L, Collections.emptyList());
            }
            wrapper.in(PaymentRecord::getOrderId, orderIds);
        }

        // 分页查询
        Page<PaymentRecord> page = paymentRecordMapper.selectPage(
                new Page<>(queryDTO.getPage(), queryDTO.getSize()),
                wrapper
        );

        // 转换为VO
        List<PaymentAdminVO> voList = page.getRecords().stream()
                .map(this::convertToAdminVO)
                .collect(Collectors.toList());

        return new PageResult(page.getTotal(), voList);
    }

    @Override
    @Transactional
    public PaymentRefundVO refund(PaymentRefundDTO refundDTO) {
        // 验证订单
        if (!"租赁单".equals(refundDTO.getOrderType())) {
            throw new BusinessException("只能退还租赁单押金");
        }

        LeaseOrder order = leaseOrderMapper.selectById(refundDTO.getOrderId());
        if (order == null) {
            throw new BusinessException("租赁订单不存在");
        }

        // 验证押金金额
        if (refundDTO.getAmount().compareTo(order.getDeposit()) > 0) {
            throw new BusinessException("退款金额不能大于押金金额");
        }

        // 生成退款编号
        String refundCode = generateRefundCode();

        // 创建退款记录
        PaymentRecord record = PaymentRecord.builder()
                .code(refundCode)
                .orderId(refundDTO.getOrderId())
                .orderType(refundDTO.getOrderType())
                // 使用负数表示退款
                .amount(refundDTO.getAmount().negate())
                .paymentType("押金")
                .paymentMethod("微信")
                // 直接设置为已退款
                .status(1)
                .paymentTime(LocalDateTime.now())
                .build();

        paymentRecordMapper.insert(record);

        return PaymentRefundVO.builder()
                .refundId(record.getPaymentId())
                .code(record.getCode())
                .status(record.getStatus())
                .build();
    }

    /**
     * 获取订单金额
     */
    private BigDecimal getOrderAmount(PaymentCreateDTO createDTO) {
        if ("租赁单".equals(createDTO.getOrderType())) {
            LeaseOrder order = leaseOrderMapper.selectById(createDTO.getOrderId());
            if (order == null) {
                throw new BusinessException("租赁订单不存在");
            }
            return "租金".equals(createDTO.getPaymentType()) ? order.getLeaseFee() : order.getDeposit();
        } else if ("维修单".equals(createDTO.getOrderType())) {
            RepairOrder order = repairOrderMapper.selectById(createDTO.getOrderId());
            if (order == null) {
                throw new BusinessException("维修订单不存在");
            }
            return order.getRepairFee();
        } else {
            throw new BusinessException("订单类型错误");
        }
    }

    /**
     * 生成支付编号
     */
    private String generatePaymentCode() {
        LocalDateTime now = LocalDateTime.now();
        String date = String.format("%tY%<tm%<td", now);

        // 查询当天最大序号
        String prefix = "P" + date;
        LambdaQueryWrapper<PaymentRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(PaymentRecord::getCode, prefix)
                .orderByDesc(PaymentRecord::getCode)
                .last("LIMIT 1");

        PaymentRecord lastRecord = paymentRecordMapper.selectOne(queryWrapper);

        int sequence = 1;
        if (lastRecord != null) {
            String lastCode = lastRecord.getCode();
            sequence = Integer.parseInt(lastCode.substring(9)) + 1;
        }

        return String.format("%s%03d", prefix, sequence);
    }

    /**
     * 生成支付链接
     */
    private String generatePaymentUrl(PaymentRecord record) {
        // TODO: 对接支付平台，生成支付链接
        return String.format("https://payment.example.com/pay/%d", record.getPaymentId());
    }

    /**
     * 转换为VO
     */
    private PaymentVO convertToVO(PaymentRecord record) {
        // 获取订单编号
        String orderCode = getOrderCode(record);

        return PaymentVO.builder()
                .paymentId(record.getPaymentId())
                .code(record.getCode())
                .orderCode(orderCode)
                .amount(record.getAmount())
                .paymentType(record.getPaymentType())
                .paymentMethod(record.getPaymentMethod())
                .status(record.getStatus())
                .paymentTime(record.getPaymentTime())
                .build();
    }

    /**
     * 获取订单编号
     */
    private String getOrderCode(PaymentRecord record) {
        if ("租赁单".equals(record.getOrderType())) {
            LeaseOrder order = leaseOrderMapper.selectById(record.getOrderId());
            return order != null ? order.getCode() : null;
        } else if ("维修单".equals(record.getOrderType())) {
            RepairOrder order = repairOrderMapper.selectById(record.getOrderId());
            return order != null ? order.getCode() : null;
        }
        return null;
    }

    /**
     * 根据用户ID获取订单ID列表
     */
    private List<Long> getOrderIdsByUserId(Long userId, String orderType) {
        if ("租赁单".equals(orderType)) {
            LambdaQueryWrapper<LeaseOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(LeaseOrder::getUserId, userId);
            return leaseOrderMapper.selectList(wrapper)
                    .stream()
                    .map(LeaseOrder::getOrderId)
                    .collect(Collectors.toList());
        } else if ("维修单".equals(orderType)) {
            LambdaQueryWrapper<RepairOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(RepairOrder::getReportUserId, userId);
            return repairOrderMapper.selectList(wrapper)
                    .stream()
                    .map(RepairOrder::getOrderId)
                    .collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    /**
     * 转换为管理端VO
     */
    private PaymentAdminVO convertToAdminVO(PaymentRecord record) {
        // 获取订单编号和用户名
        String orderCode = getOrderCode(record);
        String userName = getUserName(record);

        return PaymentAdminVO.builder()
                .paymentId(record.getPaymentId())
                .code(record.getCode())
                .orderCode(orderCode)
                .userName(userName)
                .amount(record.getAmount())
                .paymentType(record.getPaymentType())
                .paymentMethod(record.getPaymentMethod())
                .status(record.getStatus())
                .transactionId(record.getTransactionId())
                .paymentTime(record.getPaymentTime())
                .build();
    }

    /**
     * 获取用户名
     */
    private String getUserName(PaymentRecord record) {
        Long userId = null;
        if ("租赁单".equals(record.getOrderType())) {
            LeaseOrder order = leaseOrderMapper.selectById(record.getOrderId());
            if (order != null) {
                userId = order.getUserId();
            }
        } else if ("维修单".equals(record.getOrderType())) {
            RepairOrder order = repairOrderMapper.selectById(record.getOrderId());
            if (order != null) {
                userId = order.getReportUserId();
            }
        }

        if (userId != null) {
            Users user = usersMapper.selectById(userId);
            return user != null ? user.getUsername() : null;
        }
        return null;
    }

    /**
     * 生成退款编号
     */
    private String generateRefundCode() {
        LocalDateTime now = LocalDateTime.now();
        String date = String.format("%tY%<tm%<td", now);

        // 查询当天最大序号
        String prefix = "R" + date;
        LambdaQueryWrapper<PaymentRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(PaymentRecord::getCode, prefix)
                .orderByDesc(PaymentRecord::getCode)
                .last("LIMIT 1");

        PaymentRecord lastRecord = paymentRecordMapper.selectOne(queryWrapper);

        int sequence = 1;
        if (lastRecord != null) {
            String lastCode = lastRecord.getCode();
            sequence = Integer.parseInt(lastCode.substring(9)) + 1;
        }

        return String.format("%s%03d", prefix, sequence);
    }
} 